﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using GBL.Repository.CoatOfArms;
using GBL.Repository.Resources;
using GBlasonLogic.Helpers;
using GBlasonLogic.Rules;

namespace GBlasonLogic.Tools
{
    /// <summary>
    /// Contain all the geometric tools to help creating new divisions, or updating area when parents shapes changes
    /// how it works : all the tools return unique string data used to build geometry, all the logic operation are made here it's transparent for the clients
    /// if a new build require several area, it have to build him itself, calling as many methods as needed,
    /// for exemple to build 2 half split, you first build the top and then the bottom each of those are independant while building.
    /// When updating in the parameter you have to know which part is related to which update (the top or the bottom ?) it's given in the parameter
    /// </summary>
    public static class DivisionManager
    {

        /// <summary>
        /// Creates the new division(s) in function of the constraints of the parent, given the type of division to create.
        /// </summary>
        /// <param name="parentConstraints">The constraints of the parent defining how to build the new division.</param>
        /// <param name="currentConstraints">The current constraints. Contains the type of division you want to create</param>
        /// <returns>
        /// an enumeration of division that should be linked to the origin, the parent
        /// </returns>
        public static IEnumerable<Division> CreateNewDivision(ConstraintDivisionSet parentConstraints, ConstraintDivisionSet currentConstraints)
        {
            if (!DivisionPoints.Singleton.ContainsKey(currentConstraints.TypeOfDivision))
            {
                throw new NotImplementedException(currentConstraints.TypeOfDivision.ToString());
            }

            var divisions = new Collection<Division>();
            foreach (var point in currentConstraints.TypeOfDivision.GetPoints())
            {
                divisions.Add(currentConstraints.CreateSubDivision(parentConstraints, point));
            }
            return divisions;
        }

        /// <summary>
        /// Gets the path from constraints. Used to update the path when cascade updating the shapes (from the parent to the children)
        /// here because we know the type of division set expected
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="constraints">The constraints.</param>
        /// <returns></returns>
        public static String GetPathFromConstraints(ConstraintSet parent, ConstraintSet constraints)
        {
            if (constraints is ConstraintDivisionSet && parent is ConstraintDivisionSet)
            {
                return GetPathFromConstraintDivision(parent as ConstraintDivisionSet, constraints as ConstraintDivisionSet);
            }
            return null;
        }

        /// <summary>
        /// Gets the path from constraint division, there is one special return for plain divisions that do not need geometry.
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="constraint">The constraint.</param>
        /// <returns></returns>
        private static String GetPathFromConstraintDivision(ConstraintSet parent, ConstraintDivisionSet constraint)
        {
            if (constraint == null)
                return String.Empty;
            if (constraint.TypeOfDivision == DivisionType.PartyPlain)
            {
                return parent.CurrentGeometry;
            }
            var geometry = GeometryTools.PerformGeometry(parent, constraint);
            return geometry != null 
                ? geometry.Data.ToString().Replace(';', ',') 
                : String.Empty;
            //switch (constraint.TypeOfDivision)
            //{
            //    case DivisionType.PartyPlain:
            //        return parent.CurrentGeometry;
            //    case DivisionType.PartyFess:
            //    case DivisionType.PartyPale:
            //    case DivisionType.PartyBend:
            //    case DivisionType.PartyBendSinister:
            //        var geometry = GeometryTools.PerformGeometry(parent, constraint);
            //        if (geometry != null)
            //            return geometry.Data.ToString().Replace(';', ',');
            //        break;
            //}
        }
    }
}
